#! /usr/bin/python
# coding: UTF-8
__author__ = 'root'

from base import Worker
import httplib2
import ujson
from db import GetConn,CloseConn

class BusLine:
    def __init__(self,li,ln,bt,ss,et,es,ip,p,d):
        self.begin_time = bt
        self.end_station = es
        self.end_time = et
        self.isopen = ip
        self.line_name = ln
        self.price = p
        self.start_station = ss
        self.stations = []
        self.lineid = li
        self.dir = d

    def add(self,station):
        self.stations.append(station)

class BusStation:
    def __init__(self,code,bi,lat,lng,name,li,dp):
        self.code = code
        self.stationid = bi
        self.lat = lat
        self.lng = lng
        self.name = name
        self.lineid = li
        self.display = dp


class SZBusWorker(Worker):
    def __init__(self):
        super(SZBusWorker, self).__init__()
        self.desc = '深圳公交数据爬取脚本'
        self.data = []
        self.old = {}
        self.conn = GetConn()

    def __CheckStation(self,A,B):
        '检查2个Station A B是否相同'
        return A.code == B.code and A.stationid == B.stationid and A.lat == B.lat and A.lng == B.lng and A.name == B.name and A.lineid==B.lineid and A.display==B.display

    def __CheckBus(self,A,B):
        flag = A.begin_time == B.begin_time and A.end_station == B.end_station and A.end_time == B.end_time
        flag = flag and A.isopen == B.isopen and A.line_name == B.line_name and A.price == B.price
        flag = flag and A.start_station == B.start_station and A.lineid == B.lineid and A.dir == B.dir
        ret = []
        for a in A.station:
            for b in B.station:
                if a.stationid == b.stationid:
                    if not self.__CheckStation(a,b):
                        ret.append((b,3))#车站信息被修改了
                    B.station.remove(b)
                    continue
            ret.append((a,1)) #此车站信息已经被删除了
            #
        for b in B.station:
            ret.append((b,2)) #新增加的站点
        return flag,ret


    def work(self):
        #
        url = 'http://busapi.gpsoo.net/v1/bus/t_get_openlines?citycode=860515'
        h = httplib2.Http()
        resp,content = h.request(url,'GET')
        if resp.status != 200:
            print '服务器响应错误'
            return
        ret = ujson.loads(content)
        if ret['success'] != 'true':
            print '服务器返回的json提示有错误'
            return
        for l in ret['data']:
            bl = BusLine(l['id'],l['line_name'],l['begin_time'],l['start_station'],
                         l['end_time'],l['end_station'],l['isopen'],l['price'],l['dir'])
            self.data.append(bl)

        url = 'http://busapi.gpsoo.net/v1/bus/mbcommonservice?method=getlineinfo&sublineID=%s'
        for bl in self.data:
            _url = url % bl.lineid
            resp,content = h.request(_url,'GET')
            if resp.status != 200:
                print '获取路线详细信息失败'
                break
            info = ujson.loads(content)
            if info['success'] != 'true':
                print '获取路线详细信息的json提示错误'
                continue
            if not len(info['data']):
                print '没有线路相关的信息'
                continue
            line = info['data']['subline']
            i = 0
            for s in line['station']:
                bl.add(BusStation(s['code'],s['id'],s['lat'],s['lng'],s['name'],bl.lineid,i))
                i += 1

    def load(self):

        cur = self.conn.cursor()
        try:
            sql1 = 'select * from t_bus'
            sql2 = 'select * from t_station order by sDisplay'
            n1 = cur.execute(sql1)
            if not n1 :
                return
            ret = cur.fetchall()
            ll = {}
            for r in ret:
                bl = BusLine(r[0],r[6],r[1],r[8],r[4],r[3],r[5],r[7],r[2])
                self.old[bl.lineid] = bl
                ll[r[0]] = bl
            n2 = cur.execute(sql2)
            if not n2:
                return
            ret = cur.fetchall()
            for r in ret:
                s = BusStation(r[1],r[0],r[2],r[3],r[4],r[5],r[6])
                ll[r[5]].add(s)
        finally:
            cur.close()
            CloseConn()


    def save(self):
        new_bus = []
        update_bus = []
        new_station = []
        update_station = []
        del_station = []
        #比较self.old 和 self.data
        for b in self.data:
            a = self.old[b.lineid] if self.old.has_key(b.lineid) else None
            if not a:
                new_bus.append(b)
                for s in b.stations:
                    new_station.append(s)
                continue
            f,ret = self.__CheckBus(a,b)
            if f :
                update_bus.append(b)
            for r in ret:
                if r[1]==1:
                    del_station.append(r[0])
                elif r[1]==2:
                    new_station.append(r[0])
                elif r[1] == 3:
                    update_station.append(r[0])
        sql1 = '''insert into t_bus values (%s,%s,%s,%s,%s,%s,%s,%s,%s)'''
        sql2 = '''update t_bus set bBeginTime='%s',bDir=%d,bEndStation='%s',bEndEime='%s',
bIsOpen=%d,bLineName='%s',bPrice=%d,bStartStation='%s' where bBusid=%s'''
        sql3 = '''insert into t_station values (%s,%s,%s,%s,%s,%s,%s)'''
        sql4 = '''update t_station set sCode='%s',sLat=%s,sLng=%s,sName='%s',bBusid=%s,sDisplay=%s
where sStationid=%d'''
        sql5 = '''delete from t_station where sStationid in (%s)'''
        self.conn = GetConn()
        cur = self.conn.cursor()
        try:
            if len(update_bus):
                s = [(x.begin_time,x.dir,x.end_station,x.end_time,x.isopen,x.line_name,x.price,x.start_station,x.lineid) for x in update_bus]
                cur.executemany(sql2,s)
            if len(new_bus):
                s = [(x.lineid,x.begin_time,x.dir,x.end_station,x.end_time,x.isopen,x.line_name,x.price,x.start_station) for x in new_bus]
                cur.executemany(sql1, s)
                self.conn.commit()
            if len(del_station):
                s = ','.join([x.stationid for x in del_station])
                cur.execute(sql5 % s)
            if len(update_station):
                s = [(x.code,x.lat,x.lng,x.name,x.lineid,x.stationid,x.display) for x in update_station]
                cur.executemany(sql4,s)
            self.conn.commit()
            n = len(new_station)
            if n: #这里可能数据会很多，所以需要分段处理。
                print '%d个车站数据需要插入'
                while (len(new_station)):
                    a = new_station[0:200]
                    del new_station[0:200]
                    s = [(x.stationid,x.code,x.lat,x.lng,x.name,x.lineid,x.display) for x in a]
                    cur.executemany(sql3 , s)
                    self.conn.commit()
        finally:
            cur.close()
